package AST;

import java.util.ArrayList;


public class AST {
	private ArrayList<ASTNode> tree; 
	
	public AST(){
		tree = new ArrayList<ASTNode>();
	}
	
	public void addExpression(String exp){
		String s = "";
		int i = 0;
		
		//gets the first word of the expression
		while (exp.charAt(i) != ' '){
			s+= exp.charAt(i);
			i++;
			if (i == exp.length())
				break;
			
		}
		
		if (s.equals("begin")){
			tree.add(new ASTNode("Begin",""));
		}
		else if (s.equals("replace")){
			s="";
			String param1 ="";
			String param2 ="";
			String param3 ="";
			String param4 ="";
			//find '
			while (exp.charAt(i) != 39){
				i++;
			}
			i++;
			while (exp.charAt(i) != 39){
				s+=exp.charAt(i);
				i++;
			}
			param1 = s;
			s="";
			
			//find " for each parameter and add the node
			for (int j = 0;j<3;j++){
				while (exp.charAt(i) != '"'){
					i++;
				}
				i++;
				while (exp.charAt(i) != '"'){
					s+=exp.charAt(i);
					i++;
				}
				i++;
				if (j == 0)param2 = s;
				if (j == 1)param3 = s;
				if (j == 2)param4 = s;
				s="";
			}
			tree.get(0).addChild(createReplace(param1,param2,param3,param4));
		}
		else if (s.equals("recursivereplace")){
			s="";
			String param1 ="";
			String param2 ="";
			String param3 ="";
			String param4 ="";
			//find '
			while (exp.charAt(i) != 39){
				i++;
			}
			i++;
			while (exp.charAt(i) != 39){
				s+=exp.charAt(i);
				i++;
			}
			param1 = s;
			s="";
			
			//find " for each parameter and add the node
			for (int j = 0;j<3;j++){
				while (exp.charAt(i) != '"'){
					i++;
				}
				i++;
				while (exp.charAt(i) != '"'){
					s+=exp.charAt(i);
					i++;
				}
				i++;
				if (j == 0)param2 = s;
				if (j == 1)param3 = s;
				if (j == 2)param4 = s;
				s="";
			}
			tree.get(0).addChild(createRecurssiveReplace(param1,param2,param3,param4));
		}
		else if (s.equals("print")){
			String param1 = "";
			s= "";
			while ((exp.charAt(i) == '(')||(exp.charAt(i) == ' ')){
				i++;
			}
			while (exp.charAt(i) != ')'){
				s+=exp.charAt(i);
				i++;
			}
			
			param1 = s;
			tree.get(0).addChild(createPrint(param1));
			System.out.println("what");
			s="";
		}
		else if (s.equals("end")){
		}
		
		//if it is an id
		else{
			String ID = s;
			s = "";
			tree.get(0).addChild(new ASTNode("assign",ID));
			while ((exp.charAt(i) == ' ')||(exp.charAt(i) == '=')||(exp.charAt(i) == '(')){
				i++;
			}
			//gets the expression;
			while (i < exp.length()){
				s+=exp.charAt(i);
				i++;
			}
			System.out.println(s);
			//adds the new nods to the second teir assignment node
			tree.get(0).getChildren().get(tree.get(0).getChildren().size()-1).addChild(createID(s));
		}
	}
	
	public ArrayList<ASTNode> getTree(){
		return tree;
	}
	
	public ASTNode createID(String exp){
		ASTNode node = new ASTNode();
		int i = 0;
		String s = "";
		
		while ((exp.charAt(i) != ' ')&&(exp.charAt(i) != ';')&&(exp.charAt(i) != ' ')){
			s+=exp.charAt(i);
			i++;
		}
		
		if (s.equals("find")){
			String param1 = "";
			String param2 = "";
			while (exp.charAt(i) != 39){
				i++;
			}
			i++;
			while (exp.charAt(i) != 39){
				param1 += exp.charAt(i); 
				i++;
			}
			while (exp.charAt(i) != '"'){
				i++;
			}
			i++;
			while (exp.charAt(i) != '"'){
				param2 += exp.charAt(i); 
				i++;
			}
			i++;
			System.out.println(param1 + " " + param2);
			node = createFind(param1,param2);
		}
		else if (s.equals("maxfreqstring")){
			String param = "";
			while ((exp.charAt(i) == ' ')||(exp.charAt(i) == '(')){
				i++;
			}
			while((exp.charAt(i) != ' ')&&(exp.charAt(i) != ')')){
				param+=exp.charAt(i);
				i++;
			}
			System.out.println("param " + param);
			return createMaxFreq(param);
		}
		else if (exp.charAt(0) == '#'){
			s=s.replace("#", "");
			node = new ASTNode("#",s);
		}
		//get past all the white space at the end
		while ((exp.charAt(i) == ' ')||(exp.charAt(i) == ')')){
			i++;
		}
		
		if (exp.charAt(i) == ';')
			return node;
		
		while ((exp.charAt(i) == ' ')||(exp.charAt(i) == '"')){
			i++;
		}
		
		//get the nex expression
		String newExp = "";
		int j = i;
		while (exp.charAt(j) == ' ') j++;
		while (exp.charAt(j) != ' ') j++;
		while (exp.charAt(j) == ' ') j++;
		for (j = j; j < exp.length(); j++){
			newExp += exp.charAt(j);
		}
		
		//recursive call if there are any operators
		String op = "";
		while ((exp.charAt(i) != ' ')){
			op += exp.charAt(i); 
			i++;
		}
		
		ASTNode newNode = new ASTNode("operation",op);
		newNode.addChild(node);
		newNode.addChild(createID(newExp));
		
		return newNode;
	}
	
	public ASTNode createMaxFreq(String param){
		ASTNode node = new ASTNode("maxfreq");
		node.addChild(new ASTNode("data",param));
		return node;
	}
	public ASTNode createFind(String param1, String param2){
		ASTNode node = new ASTNode("find");
		node.addChild(new ASTNode("data",param1));
		node.addChild(new ASTNode("data",param2));
		return node;
	}
	
	public ASTNode createReplace(String regex, String str,String file1, String file2){
		ASTNode replaceNode = new ASTNode("replace");
		replaceNode.addChild(new ASTNode("data",regex));
		replaceNode.addChild(new ASTNode("data",str));
		replaceNode.addChild(new ASTNode("data",file1));
		replaceNode.addChild(new ASTNode("data",file2));
		return replaceNode;
	}
	public ASTNode createRecurssiveReplace(String regex, String str,String file1, String file2){
		ASTNode replaceNode = new ASTNode("RecurssiveReplace");
		replaceNode.addChild(new ASTNode("data",regex));
		replaceNode.addChild(new ASTNode("data",str));
		replaceNode.addChild(new ASTNode("data",file1));
		replaceNode.addChild(new ASTNode("data",file2));
		return replaceNode;
	}
	
	public ASTNode createPrint(String param){
		System.out.println("hey");
		ASTNode replaceNode = new ASTNode("print");
		replaceNode.addChild(new ASTNode("data",param));
		System.out.println("hey");
		return replaceNode;
	}
	
	public String toString(){
		String s = "";
		s+= "Height 0";
		s += "\nType " + tree.get(0).getType();
		s += "\nData " + tree.get(0).getData();
		s += "\n";
		s += toString (tree.get(0).getChildren(),1);
		return s;
	}
	
	public String toString(ArrayList<ASTNode> node,int height){
		String s ="";
		for (int i = 0; i < node.size();i++){
			s += "\nHeight " + height;
			s += "\nType " + node.get(i).getType();
			s += "\nData " + node.get(i).getData();
			s+="\n";
			s += toString(node.get(i).getChildren(),height + 1);
		}
		return s;
	}
}
